﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;

namespace PS.WssSync
{
    enum Operations
    {
        Invalid,
        Commit,
        Update,
        Checkout
    }

    internal static class ParamNames
    {
        public const string DirUrl      = "-url";
        public const string DirPath     = "-dir";
        public const string Overwrite   = "-overwrite";
        public const string Commit      = "-commit";
        public const string Update      = "-update";
        public const string Checkout    = "-checkout";
        public const string UserName    = "-username";
        public const string Password    = "-password";
    }

    internal class AppProperties
    {        
        public AppProperties()
        {
            Operation   = Operations.Invalid;
            DirPath     = Directory.GetCurrentDirectory();
            Credentials = CredentialCache.DefaultCredentials;
        }

        public AppProperties(IEnumerable<string> args) : this()
        {
            GetProperties(args);
        }

        public string DirUrl { get; set; }
        public string DirPath { get; set; }        
        public Operations Operation { get; set; }
        public bool Overwrite { get; set; }
        public ICredentials Credentials { get; set; }
        
        private string UserName { get; set; }
        private string Password { get; set; }
        private string Domain { get; set;}

        public void Validate()
        {
            if (Operation == Operations.Invalid)
            {
                throw new ArgumentException("no operation specified");
            }
            if (string.IsNullOrEmpty(DirUrl))
            {
                throw new ArgumentException("web url missing");
            }
            if(string.IsNullOrEmpty(DirPath))
            {
                throw new ArgumentException("directory path missing");
            }
            if (!string.IsNullOrEmpty(UserName) && !string.IsNullOrEmpty(Password))
            {
                Credentials = new NetworkCredential(UserName, Password, Domain);
            }
            else if (string.IsNullOrEmpty(UserName) && string.IsNullOrEmpty(Password))
            {
            }
            else if (string.IsNullOrEmpty(UserName) && !string.IsNullOrEmpty(Password))
            {
                throw new ArgumentException("username missing");
            }
            else
            {
                throw new ArgumentException("password missing");
            }
        }

        private void GetProperties(IEnumerable<string> args)
        {
            foreach (string arg in args)
            {
                string operation = arg;
                string argument = ExtractParam(ref operation);

                switch (operation)
                {
                    case ParamNames.DirUrl:
                        DirUrl = argument;
                        break;
                    case ParamNames.DirPath:
                        DirPath = argument;
                        break;
                    case ParamNames.Commit:
                        Operation = Operations.Commit;
                        break;
                    case ParamNames.Update:
                        Operation = Operations.Update;
                        break;
                    case ParamNames.Checkout:
                        Operation = Operations.Checkout;
                        break;
                    case ParamNames.Overwrite:
                        Overwrite = true;
                        break;
                    case ParamNames.UserName:
                        ParseUsername(argument);
                        break;
                    case ParamNames.Password:
                        Password = argument;
                        break;
                    default:
                        throw new ArgumentException("unknown param " + operation);
                }
            }
        }     

        internal static string ExtractParam(ref string operation)
        {
            int index = operation.IndexOf('=');
            string argument = string.Empty;
            if (-1 != index)
            {
                argument = operation.Substring(index + 1, operation.Length - index - 1);
                operation = operation.Substring(0, index);             
            }

            return argument;
        }

        private void ParseUsername(string userName)
        {            
            int index = userName.IndexOf('\\');
            if (-1 != index)
            {
                Domain = userName.Substring(0, index);
                UserName = userName.Substring(index + 1);
            }
            else
            {
                Domain = string.Empty;
                UserName = userName;
            }
        }   
    }
}
